<?php
	class Plan extends AppModel
	{
		var $name = "Plan";
		const PAYMENT_TRIAL = 1;
		const PAYMENT_ONE_TIME = 2;
		const PAYMENT_SUBSCRIPTION = 3;
		const PLAN_TYPE_NEW = 1;
		const PLAN_TYPE_UPGRADE = 2;
		var $fieldProperties = array();
		
		function afterInitialize()
		{
			cri("PaidListings.PaidListingConfig")->init();
			$this->fieldProperties = array(
				'title' => array('label'=>"Plan Name",'validate'=>VALID_NOT_EMPTY,'group'=>array("add"),'type'=>"text"),
				'description' => array("label"=>"Description",'group'=>array("add"),'type'=>"textarea",'row'=>4,'col'=>10,'type'=>"editor",'editorOptions'=>array('editor'=>"full")),
				'status' => array(),
				'plan_type' => array(),
				'is_default' => array("label"=>__("Is it your default plan?"),'tooltip'=>"Default plans are pre-selected on add listing page",'options'=>array(__("No"),__("Yes")),'default'=>0,'group'=>array("add")),
				'payment_type'=> array('label'=>"Select Payment type",'type'=>"select",'options'=>array(self::PAYMENT_TRIAL=>__("Free Plan/Trial"),self::PAYMENT_ONE_TIME=>__("One Time Payment"),self::PAYMENT_SUBSCRIPTION=>__("Subscription")),'group'=>array("add")),
				'price' => array('type'=>"text",'tooltip'=>"Enter price you want to charge for this plan",'class'=>'vsmall_input','group'=>array("add"),'type'=>"number",'validate'=>VALID_NOT_EMPTY,'group'=>array("add"),'default'=>0),
				'duration_number' => array('label'=>"Duration",'type'=>"number",'group'=>array("add"),'validate'=>VALID_NOT_EMPTY,'group'=>array("add")),
				'duration_period' => array('label'=>"Duration Period",'type'=>"select",'group'=>array("add"),'validate'=>VALID_NOT_EMPTY,'options'=>array(),'group'=>array("add")),
				'disable_moderation' => array("label"=>"Disable moderation",'tooltip'=>"Would you like to disable moderation when listing is added?",'type'=>"select",'options'=>array(__("No"),__("Yes")),'default'=>0,'group'=>array("add")),
				'featured' => array("label"=>"Make listing featured",'type'=>"select",'options'=>array(__("No"),__("Yes")),'default'=>0,'group'=>array("add")),
				'limit_images' => array('type'=>"checkbox",'label'=>"Limit the number of images that owner can upload?",'group'=>array("add"),'options'=>array(__("No"),__("Yes"))),
				'images' => array('type'=>"text",'label'=>"Number of images",'type'=>"text",'group'=>array("add"),'group'=>array("add")),
				'allow_gallery' => array("type"=>"checkbox",'label'=>"Allow other users to add images to gallery of the listing?",'group'=>array("add"),array(__("No"),__("Yes"))),
				'custom_fields' => array("fieldModifier"=>"toggleSerialized"),
	      		'categories' => array("fieldModifier"=>"toggleSerialized"),
				'allow_multiple_categories' => array("type"=>"checkbox",'label'=>"Allow multiple categories in listing",'group'=>array("add"))
			);
			if(cr("DealConfig.enable_deals"))
			{
				$this->setFieldProperties('enable_deals',array('type'=>"select",'label'=>__("Enable Deals"),'group'=>array("add"),'options'=>array(__("No"),__("Yes"))));
				$this->setFieldProperties('active_deals_limit',array('label'=>__("Number of active deals"),'type'=>"number",'default'=>0,'group'=>array("add"),'class'=>'vsmall_input','validate'=>array('rule'=>array('checkActiveDealsLimit'),'message'=>__("Invalid integer value"),'required'=>false,'allowEmpty'=>true)));
			}
			if(cr("EventConfig.enable_events"))
			{
				$this->setFieldProperties('limit_events',array('type'=>"select",'label'=>__("Apply limit on number of active events per listing"),'group'=>array("add"),'options'=>array(__("No"),__("Yes")),'default'=>1,'after'=>__("Select \"Yes\" to apply a limit ELSE \"No\" for no limit")));
				$this->setFieldProperties('allowed_events_limit',array('label'=>__("Maximum number of active events allowed per listing"),'type'=>"number",'default'=>0,'group'=>array("add"),'validate'=>VALID_NOT_EMPTY,'default'=>10,'class'=>'vsmall_input'));
			}
			
		    if(!cr('ListingConfig.allow_multiple_categories'))
		    {
		        $this->fieldProperties['allow_multiple_categories']['group'] = array();
		    }
			$this->fieldProperties['status'] = array("label"=>__("Status"),'options'=>array(__("Disabled"),__("Enabled")),'default'=>1,'group'=>array("add"),'type'=>"select");
			$this->fieldProperties['plan_type'] = array("label"=>"Plan type",'options'=>array(self::PLAN_TYPE_NEW => __("New Listing"),self::PLAN_TYPE_UPGRADE=>__("Upgrade Listing")),'group'=>array("add"),'validate'=>VALID_NOT_EMPTY,'default'=>self::PLAN_TYPE_NEW);
			$this->fieldProperties['price']['label'] = sprintf(__("Price (%s)"),cr("PaidListingConfig.currency"));
			$this->fieldProperties['duration_period']['options'] = array('days'=>__("Day(s)"),"weeks"=>__("Week(s)"),'months'=>__("Month(s)"),'years'=>__("Year(s)"),''=>__("Never Expires"));
			$this->fieldProperties['duration_period']['validate'] = array("rule"=>"checkDuration",'allowEmpty'=>1,'required'=>1);
			$this->fieldProperties['duration_number']['validate'] = array('required'=>1,'allowEmpty'=>true,"rule"=>"checkDuration");
			parent::afterInitialize();
		}
	
		function checkDuration()
		{
			$period = $this->data[$this->alias]['duration_period'];
			$number = $this->data[$this->alias]['duration_number'];
			if($period)
			{
				if(!is_numeric($number))
				{
					$this->invalidate("duration_number",__("Please enter a valid number."));
					return true;
				}else if(!in_array($period,array_keys($this->getFieldProperty('duration_period','options'))))
				{
					$this->invalidate("duration_number",__("Please select a period."));
					return true;
				}
				return true;
			}else
			{
				$this->data[$this->alias]['duration_number'] = 0;
				return true;
			}
		}
		function beforeDelete($cs)
		{
			GigaCache::set(array("duration"=>"+20 minutes","path"=>CACHE));
			GigaCache::delete("paidlistings_plan_map");	
			GigaModelCache::delete($this->alias,$this->id,"plan_info");
			return parent::beforeDelete($cs);
		}
                
                function beforeSave($options)
                {
                    if($this->data[$this->alias]['payment_type'] && $this->data[$this->alias]['payment_type'] == self::PAYMENT_TRIAL)
                    {
                        $this->data[$this->alias]['duration_period'] = "";
                        $this->data[$this->alias]['duration_number'] = 0;
                    }
                    return parent::beforeSave($options);
                }
		function afterSave($created)
		{
			GigaCache::set(array("duration"=>"+20 minutes","path"=>CACHE));
			GigaCache::delete("paidlistings_plan_map");	
			GigaModelCache::delete($this->alias,$this->id,"plan_info");
			parent::afterSave($created);
		}
		function getCategoryPlanMap()
		{
			$cacheKey = "paidlistings_plan_map";
			GigaCache::set(array("duration"=>"+20 minutes","path"=>CACHE));
			$categoryMap = GigaCache::read($cacheKey);
			if($categoryMap === false)
			{
				$plans = $this->find('all',array("conditions"=>array('status'=>1)));
				$categoryMap = array();
				$childrenCategoriesList = array();
				foreach($plans as $plan)
				{
					$categoryIds = $plan[$this->alias]['categories'];
					$categoryIdsNew = array();
					foreach($categoryIds as $categoryId)
					{
						if($categoryId)
						{
							$categoryIdsNew[] = $categoryId;
						}else
						{
							continue;
						}
						$childrenCategories = array();
						if(!isset($childrenCategoriesList[$categoryId]))
						{
							$children = array_keys(cri("ListCategory")->getChildrenOptions($categoryId));
							if(!$children)
							{
								$children = array();
							}
							$childrenCategoriesList[$categoryId] = $children;
						}
						$childrenCategories = $childrenCategoriesList[$categoryId];
						$categoryIdsNew = am($categoryIdsNew,$childrenCategories);
					}
					$categoryIdsNew = array_unique($categoryIdsNew);
					foreach($categoryIdsNew as $categoryId)
					{
						if($categoryId)
						{
							//categoryId	//Plan Type							//Plan ID
							$categoryMap[$categoryId][$plan[$this->alias]['plan_type']][$plan[$this->alias]['id']] = $plan[$this->alias]['id'];
						}
					}
				}
                GigaCache::set(array("duration"=>"+20 minutes","path"=>CACHE));
				GigaCache::write($cacheKey,$categoryMap);	
			}
			return $categoryMap;
		}
		function getPlansForCategory($categoryIds,$type = self::PLAN_TYPE_NEW)
		{
			if(!is_array($categoryIds))
			{
				$categoryIds = array($categoryIds);
			}
			$categoryMap = $this->getCategoryPlanMap();
			$planIds = array();
			$plans = array();
			foreach($categoryIds as $categoryId)
			{
				if(isset($categoryMap[$categoryId]) && isset($categoryMap[$categoryId][$type]))
				{
					$planIds = $categoryMap[$categoryId][$type];

					foreach($planIds as $planId)
					{
						$plans[$planId] = $this->getPlanInfo($planId);
					}
				}
			}
			return $plans;
		}
		
		function getPlanInfo($planId)
		{
			$cacheKey = "plan_info";
			$plan = GigaModelCache::read($this->alias,$planId,$cacheKey,array("duration"=>"+2 hours"));
			if($plan === false)
			{
				$plan = $this->findById($planId);
				if(!$plan)
				{
					$plan = array();
				}
				GigaModelCache::write($this->alias,$planId,$cacheKey,$plan,array("duration"=>"+2 hours"));
			}
			return $plan;
		}
		
		function getNewListingPlans($categoryIds)
		{
			$plans = $this->getPlansForCategory($categoryIds,self::PLAN_TYPE_NEW);
			return $plans;
		}
		function getUpgradePlans($categoryIds)
		{
			$plans = $this->getPlansForCategory($categoryIds,self::PLAN_TYPE_UPGRADE);
			return $plans;
		}
		function getNewListingDefaultPlan($categoryIds)
		{
			$plans = $this->getNewListingPlans($categoryIds);
			$defaultPlan = null;
			$plan = null;
			foreach($plans as $plan)
			{
				if($plan[$this->alias]['is_default'])
				{
					$defaultPlan = $plan;
					break;	
				}
			}
			return $defaultPlan;
		}
		
		function getNewTypePlanForListing($planId,$categoryIds)
		{
			$defaultPlan = $this->getNewListingDefaultPlan($categoryIds);
			$plan = null;
			if($planId)
			{
				$plans = $this->getNewListingPlans($categoryIds);
				foreach($plans as $categoryPlan)
				{
						if($categoryPlan[$this->alias]['id'] == $planId)
						{
							$plan = $categoryPlan;
							break;
						}
				}	
			}else
			{
				$plan = $defaultPlan;
			}
			return $plan;
		}

		function isValidUpgradePlan($planId,$categoryId)
		{
			$plans = $this->getUpgradePlans($categoryId);
			$valid = false;
			foreach($plans as $plan)
			{
				if($plan[$this->alias]['id'] == $planId)
				{
					$valid = true;
					break;
				}

			}
			return $valid;
		}
		//a cache Function for checking that plan for  Category exist.
		//This method could have been ListCategory Model.To keep PaidListing in app to minimum
		function hasPlans($categoryId)
		{
			$cachKey = "category_plan_count";
			$planCount = GigaModelCache::read($this->alias, $categoryId, $cachKey);
			if($planCount === false)
			{
				$planCount = count($this->getUpgradePlans($categoryId));
				$planCount = $planCount + count($this->getNewListingPlans($categoryId));
				GigaModelCache::write($this->alias, $categoryId, $planCount,$cachKey);
			}
			return $planCount > 0;
		}
		
		function toggleSerialized($value,$opreation,$plan,$field)
		{
			if($field == "custom_fields")
			{
				if($opreation == self::READ)
				{
					$value = parent::toggleSerialized($value,$opreation,$plan,$field);
					if(isset($value['fieldsets']) && is_string($value['fieldsets']) && strlen($value['fieldsets']))
					{
						$value['fieldsets'] = explode(",",$value['fieldsets']);
					}else if(!is_array($value['fieldsets']))
					{
						$value['fieldsets'] = array();
					}
					if(isset($value['fields']) && is_string($value['fields']) && strlen($value['fields']))
					{
						$value['fields'] = explode(",",$value['fields']);
					} else if(!is_array($value['fieldsets']))
					{
							$value['fields'] = array();
					}
					$value['fields'] = Set::filter($value['fields']);
					$value['fieldsets'] =Set::filter($value['fieldsets']);
				}else
				{
					$value['fieldsets'] = explode(",",$value['fieldsets']);
					$value['fields'] = explode(",",$value['fields']);
					$value = parent::toggleSerialized($value,$opreation,$plan,$field);
				}
			}else if($field == "categories")
			{
					if($opreation == self::READ)
					{
						$value = explode(",",$value);
					}
			}
			return $value;
		}
    
    function getEditateFields()
    {
        $fields = array("featured","limit_images","images","allow_gallery");
        if(cr('ListingConfig.allow_multiple_categories'))
        {
            $fields [] = "allow_multiple_categories";
        }
        if(cr("DealConfig.enable_deals"))
        {
        	$fields[] = 'enable_deals';
        	$fields[] = 'active_deals_limit';
        }
        if(cr("EventConfig.enable_events"))
        {
        	$fields[] = 'limit_events';
        	$fields[] = 'allowed_events_limit';
        }
        return $fields;
    }
    
    function checkActiveDealsLimit($params)
    {
    	$result = true;
    	if(isset($this->data[$this->alias]['enable_deals']) && ($this->data[$this->alias]['enable_deals']==1 || $this->data[$this->alias]['enable_deals']=="1"))
    	{
    		if (!$this->data[$this->alias]['active_deals_limit'] || !preg_match('/^\d+$/', $this->data[$this->alias]['active_deals_limit']))
    		{
    			$result = false;
    		}
    	}
    	return $result;
    }
    
    
}
?>